<?PHP
#
#   FILE:  AddClassification.php
#
#   Part of the Metavus digital collections platform
#   Copyright 2011-2020 Edward Almasy and Internet Scout Research Group
#   http://metavus.net
#

use Metavus\Classification;
use Metavus\ClassificationFactory;
use Metavus\FormUI;
use Metavus\MetadataField;
use Metavus\Qualifier;
use ScoutLib\StdLib;

# ----- EXPORTED FUNCTIONS ---------------------------------------------------

/**
 * Validation function for classification name field.
 * @param string $FieldName Name of field being validated.
 * @param string $FieldValue Value to validate.
 * @param array $AllFieldValues Containing values for all fields.
 * @param int $FieldId ID of field in order to check if segment name is already in use.
 * @param int $ParentId ID of parent in order to construct full classification name.
 * @return string|null NULL if field input is valid, otherwise error message.
 */
function segmentValidateFunc(string $FieldName, string $FieldValue, array $AllFieldValues, int $FieldId, int $ParentId)
{
    $FieldValue = trim($FieldValue);
    # get full name for potential new classification
    if ($ParentId == Classification::NOPARENT) {
        $NewFullName = $FieldValue;
    } else {
        $ParentClass = new Classification($ParentId);
        $NewFullName = $ParentClass->Name()." -- ".$FieldValue;
    }
    # if classification already exists return error
    $CFactory = new ClassificationFactory($FieldId);
    if ($CFactory->NameIsInUse($NewFullName)) {
        return "A classification with that name is already in use.";
    }

    return null;
}

/**
 * Get array of qualifers to display in FormUI fields
 * @param int $FieldId ID of metadata field for classification.
 * @return array Items containing qualifier names indexed by ID with placeholder for no qualifier selected
 */
function getQualifiers(int $FieldId): array
{
    $Field = new MetadataField($FieldId);

    $Items[-1] = "--";
    if ($Field->HasItemLevelQualifiers()) {
        $Items += $Field->AssociatedQualifierList();
    } elseif ($Field->DefaultQualifier() != false) {
        $Qualifier = new Qualifier($Field->DefaultQualifier());
        $Items[$Qualifier->Id()] = $Qualifier->Name();
    }
    ksort($Items);
    return $Items;
}

/**
 * Set up and return array of form field defintions for FormUI to display.
 * @param int $FieldId ID of field for displaying field name.
 * @param int $ParentId ID of parent for displaying classification to be added under.
 * @return array Form field definitions.
 */
function getFormFieldDefinitions(int $FieldId, int $ParentId): array
{
    # If parent doesn't exist
    if ($ParentId == Classification::NOPARENT) {
        # set parent classification name to '(top)'
        $ParentClassName = "(top)";
    } else {
        # otherwise set parent classification name to parent classification's name
        $ParentClass = new Classification($ParentId);
        $ParentClassName = $ParentClass->FullName();
    }

    # Get field and field name using field id.
    $FieldName = (new MetadataField($FieldId))->GetDisplayName();

    return [
    "ClassificationType" => [
        "Type" => FormUI::FTYPE_CUSTOMCONTENT,
        "ReadOnly" => true,
        "Label" => "Classification Type",
        "Content" => $FieldName,
    ],
    "ToBeAddedUnder" => [
        "Type" => FormUI::FTYPE_CUSTOMCONTENT,
        "ReadOnly" => true,
        "Label" => "To Be Added Under",
        "Content" => $ParentClassName,
    ],
    "NewSegmentName" => [
        "Type" => FormUI::FTYPE_TEXT,
        "Label" => "Segment Name",
        "Placeholder" => "Segment Name",
        "ValidateFunction" => "segmentValidateFunc",
        "Required" => true,
        "Placeholder" => "(segment name)"
    ],
    "QualifierId" => [
        "Type" => FormUI::FTYPE_OPTION,
        "Label" => "Qualifier",
        "Options" => getQualifiers($FieldId),
        "Value" => -1,
    ],
    ];
}


# ----- LOCAL FUNCTIONS ------------------------------------------------------

# ----- MAIN -----------------------------------------------------------------

if (!CheckAuthorization(PRIV_CLASSADMIN)) {
    return;
}

# get ParentId and FieldId from form or url
$ParentId = StdLib::getFormValue("F_ParentId", StdLib::getFormValue("ParentId", Classification::NOPARENT));
$FieldId = StdLib::getFormValue("F_FieldId", StdLib::getFormValue("FieldId", false));

# get form fields using FieldId and ParentId
$FormFields = getFormFieldDefinitions($FieldId, $ParentId);

# instantiate FormUI using defined fields
$H_FormUI = new FormUI($FormFields);

# add hidden values to form
$H_FormUI->AddHiddenField("F_ParentId", $ParentId);
$H_FormUI->AddHiddenField("F_FieldId", $FieldId);
$H_FormUI->AddValidationParameters($FieldId, $ParentId);
# act on any button push
$ButtonPushed = StdLib::getFormValue("Submit");
switch ($ButtonPushed) {
    case "Add":
        # check values and bail out if any are invalid
        if ($H_FormUI->ValidateFieldInput()) {
            return;
        }
        $ClassValues = $H_FormUI->GetNewValuesFromForm();
        $NewSegmentName = trim($ClassValues["NewSegmentName"]);
        $QualifierId = $ClassValues["QualifierId"];

        # add new classification
        $Class = Classification::Create(
            $NewSegmentName,
            $FieldId,
            $ParentId
        );

        # add qualifier ID (if any)
        if (isset($QualifierId) && strlen($QualifierId)) {
            $Class->QualifierId($QualifierId);
        }

        # if errors were not found
        if (!$H_FormUI->ErrorsLogged()) {
            # set parent ID to classification if it is top level, otherwise its parent
            $ParentIdForUrl = ($ParentId == Classification::NOPARENT) ? $Class->Id() : $ParentId;

            # go to classification selection page for parent of edited classification
            $GLOBALS["AF"]->SetJumpToPage("EditClassifications&FieldId=".$FieldId
                       ."&ParentId=".$ParentIdForUrl);
        }
        break;
    case "Cancel":
        $GLOBALS["AF"]->SetJumpToPage("EditClassifications");
        break;
}
